import { HealthCheckWithScreenTask, V3proLastErrCache } from "./health.check.class";
import { SendboxKey, V3proSubjectMessage } from "../model/v3pro.model";
import {
  V3proScreen,
  V3proScreenAllStatus,
  V3proSendBoxOutPort,
} from "../../../api/v3pro-api/v3pro.api.response.model";
import { HealthDescEnum, V3proAlertMessageErrTypeEnum } from "../model/v3pro.enum";
import { V3proScreenLayoutHelper } from "../helper/v3pro.screen.layout.helper";
import { V3proAllStatusLambda } from "../helper/v3pro.all.status.lambda.helper";
import { appConfig } from "../../../configs/env.config.load";
import { V3proFileHelper } from "../helper/v3pro.file.helper";
import { V3proScreenImageHelper } from "../helper/v3pro.screen.image.helper";
import { V3proCheckSendboxSignalInputTask } from "./v3pro.check.sendbox.signal.input.task";
import { V3proCheckScanboardCommTask } from "./v3pro.check.scanboard.comm.task";

/**
 * 发送盒网络物理链接故障
 *
 * 是否支持阈值设置： N
 *
 * 查询周期:
 * 定时查询
 * 间隔15秒
 * 连续3次
 *
 * 告警产生的原因:
 * 发送盒网口无网络连接
 *
 * 异常现象:
 * 发送盒该网口带载机箱显示画面冻住
 * 发送盒该网口带载机箱显示黑屏
 *
 * 维修建议:
 * 依次排查该网口网线、发送盒硬件
 *
 * 告警级别: 紧急
 */
const errCache = new V3proLastErrCache<SendboxKey>();
export class V3proCheckSendboxNetworkLinkTask extends HealthCheckWithScreenTask<
  [SendboxKey[], V3proSendBoxOutPort[]]
> {
  async checkResult(
    keyParams: [SendboxKey[], V3proSendBoxOutPort[]],
    screenId: string,
    allStatus: V3proScreenAllStatus,
    screenLayoutHelper: V3proScreenLayoutHelper,
  ) {
    const message = new V3proSubjectMessage();
    if (keyParams[0].length === 0) return message;
    message.setErrStatus();
    keyParams[1].forEach((port) => {
      port.scanBoards.forEach(({ id }) => {
        screenLayoutHelper.setScanBoardErrById(id, 1);
      });
    });
    message.files = [
      await V3proFileHelper.sendBoxKey2File(keyParams[0]),
      await new V3proScreenImageHelper(screenLayoutHelper, ["scanBoard"])
        .draw()
        .export2AlertMessageFile(),
    ];
    return message;
  }

  async genKeyParams(
    allStatus: V3proScreenAllStatus,
    screen: V3proScreen,
    screenLayoutHelper: V3proScreenLayoutHelper,
  ): Promise<[SendboxKey[], V3proSendBoxOutPort[]]> {
    const [errs, normals] = V3proAllStatusLambda.filterSendBoxesWithRemove(
      allStatus,
      V3proAllStatusLambda.healthDescrWithStatusEquals(HealthDescEnum.COMM_NODE_ERR),
      false,
    );
    const [errPorts, _] = V3proAllStatusLambda.filterSendBoxOutPortNetworkWithRemove(
      allStatus,
      (port) => port.healthStatus === "ERROR",
    );

    this.__startChildTask(
      new V3proCheckSendboxSignalInputTask(allStatus, screenLayoutHelper.clone()),
    );
    this.__startChildTask(new V3proCheckScanboardCommTask(allStatus, screenLayoutHelper.clone()));

    return [
      errCache.mergeCache(
        errs.map(SendboxKey.build),
        normals.map(SendboxKey.build),
        screen.id,
        (s) => s.id,
      ),
      errPorts,
    ];
  }

  genSRMqttTopic(
    message: V3proSubjectMessage,
    screenId: string,
    allStatus: V3proScreenAllStatus,
  ): string {
    return `notify/alert/ssads/device-led-disp:sendbox-port-error/${screenId}`;
    // return "发送盒网络物理链接故障";
  }

  getV3proAlertMessage(): V3proAlertMessageErrTypeEnum {
    return V3proAlertMessageErrTypeEnum.SEND_BOX_NETWORK_LINK;
  }

  isNeedUploadFile(
    message: V3proSubjectMessage,
    screenId: string,
    allStatus: V3proScreenAllStatus,
  ): boolean {
    return message.isErrStatus();
  }

  isReportEnabled(keyParams: any, screenId: string): boolean {
    return appConfig.v3pro.errEnable.sendBoxNet;
  }
}
